package com.progenies.ecg.asm31.model.codeparts;

import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import com.progenies.ecg.asm31.util.BytecodeInstructionsUtils;
import com.progenies.ecg.asm31.util.VariableRegister;
import com.progenies.ecg.model.AbstractCodeObject;
import com.progenies.ecg.model.codeparts.CodeBlock;
import com.progenies.ecg.model.codeparts.IfElseCodePart;
import com.progenies.ecg.model.conditions.ICondition;

public class IfCodePartASM31 extends IfElseCodePart implements IConfigurableCodePart
{
	

	private MethodVisitor visitor;
	private AbstractCodeObject parent;
	private VariableRegister varRegister;

	public IfCodePartASM31(ICondition condition, CodeBlock bodyBlock)
	{
		this.condition=condition;
		this.bodyBlock=bodyBlock;
	}

	public IfCodePartASM31(ICondition condition, CodeBlock mainCodeBlock, CodeBlock elseCodeBlock) {
		this(condition, mainCodeBlock);
		this.elseBlock=elseCodeBlock;
	}

	@Override
	public void generateBytecode() {
		
		//labels for if and else blocks
		Label endBlockLabel=new Label();
		Label elseBlockLabel=this.elseBlock==null?null:new Label();

		//Evaluate conditions (even combinations)
		BytecodeInstructionsUtils.evaluateCondition(visitor, this.condition, elseBlockLabel!=null?elseBlockLabel:endBlockLabel, varRegister, parent);
		
		
		//body block
		this.bodyBlock.generateBytecode();
		
		//if there are an else block, visit label and code
		if(elseBlockLabel!=null)
		{
			//if i was on the OK body, jump to the end
			visitor.visitJumpInsn(Opcodes.GOTO, endBlockLabel);
			
			//else block
			visitor.visitLabel(elseBlockLabel);
			elseBlock.generateBytecode();
		}
		
		//end of if block
		visitor.visitLabel(endBlockLabel);

	}
	
	
	
	
	

	@Override
	public boolean isReturnCodePart() {
		return false;
	}

	@Override
	public void configure(MethodVisitor visitor, AbstractCodeObject parent,	VariableRegister varRegister)
	{
		this.visitor=visitor;
		this.parent=parent;
		this.varRegister=varRegister;
		
		if(this.bodyBlock!=null) ((IConfigurableCodePart)bodyBlock).configure(visitor, parent, varRegister);
		if(this.elseBlock!=null) ((IConfigurableCodePart)elseBlock).configure(visitor, parent, varRegister);
		
	}

}
